home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
winsock
/
ircii2-6.zip
/
SRC\IRCII-2.6\SOURCE\MENU.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-28
|
9KB
|
418 lines
/*
* menu.c: stuff for the menu's..
*
* Written By Troy Rollo <troy@cbme.unsw.oz.au>
*
* Copyright(c) 1991/1992.
*
* See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
*/
#ifndef lint
static char rcsid[] = "@(#)$Id: menu.c,v 1.7 1994/07/02 02:32:13 mrg Stab $";
#endif
#include "irc.h"
#include "menu.h"
#include "list.h"
#include "ircaux.h"
#include "term.h"
#include "window.h"
#include "screen.h"
#include "input.h"
#include "vars.h"
#include "output.h"
Menu *MenuList = (Menu *) 0;
struct OptionTableTag
{
char *name;
void (*func)();
};
typedef struct OptionTableTag OptionTable;
static OptionTable OptionsList[] =
{
{ "PREVIOUS", menu_previous },
{ "MENU", menu_submenu },
{ "EXIT", menu_exit },
{ "CHANNELS", menu_channels },
{ "COMMAND", menu_command },
{ (char *) 0, (void (*) ()) 0}
};
MenuOption *create_new_option()
{
MenuOption *NewOption;
NewOption = (MenuOption *) new_malloc(sizeof(MenuOption));
NewOption->Name = (char *) 0;
NewOption->Arguments = (char *) 0;
NewOption->Func = (void (*) ()) 0;
return NewOption;
}
Menu *create_new_menu()
{
Menu *NewMenu;
NewMenu = (Menu *) new_malloc(sizeof(Menu));
NewMenu->Name = (char *) 0;
NewMenu->TotalOptions = 0;
NewMenu->Options = (MenuOption **) 0;
return NewMenu;
}
void install_menu(NewMenu, TotalMade)
Menu *NewMenu;
int TotalMade;
{
MenuOption **NewOptions;
int i;
if (!NewMenu)
return;
if (TotalMade != NewMenu->TotalOptions)
{
NewOptions = (MenuOption **) malloc(TotalMade *
sizeof(MenuOption *));
for (i = 0; i < TotalMade; i++)
NewOptions[i] = NewMenu->Options[i];
new_free(&NewMenu->Options);
NewMenu->Options = NewOptions;
NewMenu->TotalOptions = TotalMade;
}
add_to_list(&MenuList, NewMenu);
say("Menu \"%s\" added", NewMenu->Name);
}
void load_menu(FileName)
char *FileName;
{
FILE *fp;
Menu *NewMenu = NULL;
char *line, *command;
int linenum = 0;
int CurTotal = 0;
char *name, *func;
int FuncNum;
MenuOption **NewOptions;
int i;
if ((fp = fopen(FileName, "r")) == (FILE *) 0)
{
say("Unable to open %s", FileName);
return;
}
while (fgets(buffer, BIG_BUFFER_SIZE, fp))
{
buffer[strlen(buffer)-1] = '\0';
linenum++;
line = buffer;
while (isspace(*line))
line++;
if (*line == '#' || !(command = next_arg(line, &line)))
continue;
if (!my_stricmp(command, "MENU"))
{
if (!line || !*line)
{
put_it("Missing argument in line %d of %s",
linenum, FileName);
continue;
}
install_menu(NewMenu, CurTotal);
NewMenu = create_new_menu();
malloc_strcpy(&NewMenu->Name, line);
}
else if (!my_stricmp(command, "OPTION"))
{
if (!(name = new_next_arg(line, &line)) ||
!(func = next_arg(line, &line)))
{
say("Missing argument in line %d of %s",
linenum, FileName);
continue;
}
for (i=0; OptionsList[i].name; i++)
if (!my_stricmp(func, OptionsList[i].name))
break;
if (!OptionsList[i].name)
{
say("Unknown menu function \"%s\" in line %d \
of %s",
func, linenum, FileName);
continue;
}
FuncNum = i;
if (++CurTotal > NewMenu->TotalOptions)
{
NewOptions = (MenuOption **)
new_malloc(sizeof(MenuOption *) *
(CurTotal+4));
for (i = 0; i < NewMenu->TotalOptions; i++)
NewOptions[i] = NewMenu->Options[i];
new_free(&NewMenu->Options);
NewMenu->Options = NewOptions;
NewMenu->TotalOptions = CurTotal + 5;
}
NewMenu->Options[CurTotal-1] = create_new_option();
malloc_strcpy(&NewMenu->Options[CurTotal-1]->Name,
name);
malloc_strcpy(&NewMenu->Options[CurTotal-1]->Arguments,
line);
NewMenu->Options[CurTotal-1]->Func =
OptionsList[FuncNum].func;
}
else
say("Unkown menu command in line %d of %s",
linenum, FileName);
}
install_menu(NewMenu, CurTotal);
fclose(fp);
}
int ShowMenuByWindow(window, flags)
Window *window;
int flags;
{
int i;
int largest;
int NumPerLine;
int len;
WindowMenu *menu_info;
Menu *ThisMenu;
int CursorLoc;
menu_info = &window->menu;
ThisMenu = menu_info->menu;
CursorLoc = menu_info->cursor;
largest = 0;
for (i = 0; i < ThisMenu->TotalOptions; i++)
if ((len = strlen(ThisMenu->Options[i]->Name))>largest)
largest = len;
NumPerLine = (CO - CO % (largest + 3)) / (largest + 3);
menu_info->items_per_line = NumPerLine;
menu_info->lines = 0;
for (i = 0; i < ThisMenu->TotalOptions; i++)
{
if ((flags & SMF_ERASE) && !(i % NumPerLine) &&
!(flags & SMF_CALCONLY))
{
term_move_cursor(0, window->top + menu_info->lines);
term_clear_to_eol();
}
if ((i == CursorLoc || !(flags&SMF_CURSONLY)) &&
!(flags & SMF_CALCONLY))
{
if (i == CursorLoc && !(flags & SMF_NOCURSOR) &&
current_screen->inside_menu == 1)
term_standout_on();
else
term_bold_on();
term_move_cursor((i % NumPerLine) * (largest + 3),
window->top+menu_info->lines);
fwrite(ThisMenu->Options[i]->Name,
strlen(ThisMenu->Options[i]->Name), 1, stdout);
if (i == CursorLoc && !(flags & SMF_NOCURSOR))
term_standout_off();
else
term_bold_off();
}
if (!((i + 1) % NumPerLine))
menu_info->lines++;
}
if (i % NumPerLine)
menu_info->lines++;
window->display_size = window->bottom - window->top - menu_info->lines;
if (window->cursor < 0)
window->cursor = 0;
fflush(stdout);
update_input(UPDATE_JUST_CURSOR);
return ThisMenu->TotalOptions;
}
void ListMenu(ThisMenu)
Menu *ThisMenu;
{
int i;
int j;
for (i = 0; i < ThisMenu->TotalOptions; i++)
{
for (j = 0; ThisMenu->Options[i]->Func != OptionsList[j].func;
j++);
say(" %-10s\t%-10s\t%s", ThisMenu->Options[i]->Name,
OptionsList[j].name,
ThisMenu->Options[i]->Arguments?
ThisMenu->Options[i]->Arguments:"");
}
}
int ShowMenu(Name)
char *Name;
{
Menu *ThisMenu;
Window *window;
WindowMenu *menu_info;
window = curr_scr_win;
menu_info = &window->menu;
ThisMenu = (Menu *) find_in_list(&MenuList, Name, 0);
if (!ThisMenu)
{
say("No such menu \"%s\"", Name);
return -1;
}
menu_info->cursor = 0;
menu_info->menu = ThisMenu;
return ShowMenuByWindow(window, SMF_CALCONLY);
}
void set_menu(Value)
char *Value;
{
Window *window;
WindowMenu *menu_info;
ShrinkInfo SizeInfo;
window = curr_scr_win;
menu_info = &window->menu;
if (!Value)
{
window->display_size = window->bottom - window->top;
menu_info->menu = (Menu *) 0;
menu_info->lines = 0;
SizeInfo = resize_display(window);
redraw_resized(window, SizeInfo, 0);
update_input(UPDATE_JUST_CURSOR);
current_screen->inside_menu = -1;
}
else
{
if (ShowMenu(Value) == -1)
{
set_string_var(MENU_VAR, NULL);
return;
}
SizeInfo = resize_display(window);
redraw_resized(window, SizeInfo, 0);
ShowMenuByWindow(window, SMF_ERASE);
/*
redraw_window(window);
*/
}
}
void enter_menu()
{
if (!curr_scr_win->menu.menu)
return;
current_screen->inside_menu = 1;
ShowMenuByWindow(curr_scr_win, SMF_CURSONLY);
}
void menu_previous(args)
char *args;
{
}
void menu_submenu(args)
char *args;
{
}
void menu_exit(args)
char *args;
{
current_screen->inside_menu = -1;
}
void menu_channels(args)
char *args;
{
}
void menu_key(key)
char key;
{
Window *window;
WindowMenu *menu_info;
Menu *ThisMenu;
window = curr_scr_win;
menu_info = &window->menu;
ThisMenu = menu_info->menu;
ShowMenuByWindow(window, SMF_CURSONLY | SMF_NOCURSOR);
switch(key)
{
case 'U':
case 'u':
case 'P':
case 'p':
case 'k':
case 'K':
case 'U' - '@':
case 'P' - '@':
menu_info->cursor-=menu_info->items_per_line;
break;
case 'n':
case 'd':
case 'j':
case 'N':
case 'D':
case 'J':
case 'D' - '@':
case 'N' - '@':
menu_info->cursor+=menu_info->items_per_line;
break;
case 'b':
case 'h':
case 'B':
case 'H':
case 'B' - '@':
menu_info->cursor--;
break;
case 'f':
case 'l':
case 'F':
case 'L':
case 'F' - '@':
menu_info->cursor++;
break;
case '\033':
break;
case '\r':
case '\n':
hold_mode((Window *) 0, OFF, 1);
break;
case ' ':
case '.':
current_screen->inside_menu = 0;
ThisMenu->Options[menu_info->cursor]->Func(
ThisMenu->Options[menu_info->cursor]->Arguments);
if (current_screen->inside_menu != -1)
current_screen->inside_menu = 1;
else
current_screen->inside_menu = 0;
return; /* The menu may not be here any more */
}
if (menu_info->cursor>=menu_info->menu->TotalOptions)
menu_info->cursor = menu_info->menu->TotalOptions - 1;
if (menu_info->cursor < 0)
menu_info->cursor = 0;
if (current_screen->inside_menu)
ShowMenuByWindow(window, SMF_CURSONLY);
}
void menu_command(args)
char *args;
{
parse_line((char *) 0, args, empty_string, 0, 0);
}